#include <iostream>
#include <fstream>
#include <vector>
#include <pthread.h>
#include <stdlib.h>//srand(),rand()

using namespace std;

//最终需要和单个缓存的搬运效率做比较

const int BUFSIZE = 5;

std::vector<int> buf1(BUFSIZE, 0);
std::vector<int> buf2(BUFSIZE, 0);

/*将数据从内存向磁盘搬运*/
pthread_cond_t bufisempty1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t bufisempty2 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
bool isempty1 = true;
bool isempty2 = true;

void *consumer(void *p)
{
	fstream tmpfile ("tmp.data", ios::out /*| ios::app*/ | ios::binary );
	vector<int>::iterator it;
	bool switchbuf = false;
	for (;;) {
		
		//通过switchbuf保证搬运的顺序
		if ( switchbuf )
		{
			cout << "cycle in consumer try to lock buf2." << endl;

			//如果缓存2非空
			if ( false == isempty2 )
			{
				pthread_mutex_lock(&lock2);
				//一次性向磁盘写入BUFSIZE个元素
				for (it = buf2.begin(); it != buf2.end(); it++)
				{
					tmpfile << *it << endl;
					*it = 0;
				}
				cout << "Consume 2 " << endl;
				switchbuf = false;
				isempty2 = true;
				pthread_mutex_unlock(&lock2);
				pthread_cond_signal(&bufisempty2);
			}
		}
		else
		{
			cout << "cycle in consumer try to lock buf1." << endl;

			//如果缓存1非空
			if ( false == isempty1 )
			{
				pthread_mutex_lock(&lock1);
				//一次性向磁盘写入BUFSIZE个元素
				for (it = buf1.begin(); it != buf1.end(); it++)
				{
					tmpfile << *it << endl;
					*it = 0;
				}
				cout << "Consume 1 " << endl;
				switchbuf = true;
				isempty1 = true;
				pthread_mutex_unlock(&lock1);
				pthread_cond_signal(&bufisempty1);
			}
		}
		int sec = rand() % 3;
		cout << "will wait " << sec << " sec" << endl << endl;
		sleep(sec);
	}
}


int main ()
{
	pthread_t cid;

	srand(time(NULL));
	vector<int>::iterator it;
	pthread_create(&cid, NULL, consumer, NULL);

	bool switchbuf = false;
	for (;;) {
		int tmp = rand();

		//通过switchbuf保证写入的顺序（谁空写谁呢？）
		if ( switchbuf )
		{
			cout << "cycle in produce try to lock buf2." << endl;

			pthread_mutex_lock(&lock2);
			//当缓存2非空
			while ( false == isempty2 )
			{
				cout << "2 wait ..." << endl;
				cout << pthread_cond_wait(&bufisempty2, &lock2) << endl;
			}
			//一次性向内存写入BUFSIZE个元素
			for (it = buf2.begin(); it != buf2.end(); it++)
			{
				*it = tmp;
			}
			cout << "Produce 2 " << endl;
			switchbuf = false;
			isempty2 = false;
			pthread_mutex_unlock(&lock2);
		}
		else
		{
			cout << "cycle in produce try to lock buf1." << endl;

			pthread_mutex_lock(&lock1);
			//当缓存1非空
			while ( false == isempty1 )
			{
				cout << "1 wait ..." << endl;
				cout << pthread_cond_wait(&bufisempty1, &lock1) << endl;
			}
			//一次性向内存写入BUFSIZE个元素
			for (it = buf1.begin(); it != buf1.end(); it++)
			{
				*it = tmp;
			}
			cout << "Produce 1 " << endl;
			switchbuf = true;
			isempty1 = false;
			pthread_mutex_unlock(&lock1);
		}

		int sec = rand() % 3;
		cout << "will wait " << sec << " sec" << endl << endl;
		sleep(sec);
	}

	pthread_join(cid, NULL);

	return 0;
}
